/*
 * Daniel R Padilla
 *
 * Copyright (c) 2008, Daniel R Padilla
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.databasefacade.select.functions;

import java.util.ArrayList;

import org.databasefacade.exception.DatabaseFacadeException;
import org.databasefacade.translator.Translator;

/**
 * Function classes must implement this interface
 * so that they can be stored in a function list
 * for statement retrieval.
 */
public interface Function {
	// Aggregate Functions
	public static final String COUNT="COUNT";
	public static final String MAX="MAX";
	public static final String MIN="MIN";
	public static final String AVG="AVG";
	public static final String SUM="SUM";
	public static final String STDEV="STDEV";
	public static final String VARIANCE="VARIANCE";
	
	// String Functions
	public static final String TRIM="TRIM";
	public static final String CHAR_LENGTH="CHAR_LENGTH";
	public static final String SUBSTRING="SUBSTRING";

	
	// Mathematical Functions
	public static final String ABS="ABS";
	public static final String MOD="MOD";
	public static final String POW="POW";
	public static final String ROUND="ROUND";
	public static final String SQRT="SQRT";
	public static final String COS="COS";
	public static final String SIN="SIN";
	public static final String TAN="TAN";
	public static final String ACOS="ACOS";
	public static final String ASIN="ASIN";
	public static final String ATAN="ATAN";
	
	// Date Functions
	public static final String CURDATE="CURRDATE";
	public static final String CURTIME="CURTIME";
	public static final String NOW="NOW";
	public static final String DAY="DAY";
	public static final String MONTH="MONTH";
	public static final String YEAR="YEAR";
	public static final String HOUR="HOUR";
	public static final String MINUTE="MINUTE";
	public static final String TIME_ADD="TIME_ADD";
	public static final String TIME_DIFF="TIME_DIFF";
	public static final String DAYOFWEEK="DAYOFWEEK";
	public static final String DAYOFMONTH="DAYOFMONTH";
	public static final String DAYOFYEAR="DAYOFYEAR";
	
	// Utility Functions
	public static final String REPLACE_IF_NULL="REPLACE_IF_NULL";
	
	
	// If the function is an aggregate it must be supported
	public String getFunctionType();
	public boolean isAggregate();
	public ArrayList getParameters();
	
	/**
	 * Lets the database facade know if the
	 * functionality is supported.
	 * 
	 * @return
	 */
	public boolean isSupported();
	
	/**
	 * If the function is not supported by
	 * the function then return the column
	 * and java will apply the function to
	 * the query result set.
	 * 
	 * @return
	 */
	public String getSQL(Translator translator);
	
	/**
	 * This implements a method that is
	 * applied to the data returned by 
	 * the query if the database does not
	 * support the functionality.
	 * 
	 * Aggregate Functions cannot make use of this
	 * functionality. That is why aggregates will
	 * only accept columns or operators. Aggregates
	 * are applied to the entire result set and the
	 * aggregates listed in this interface are supported
	 * by most major databases.
	 * 
	 * @param value
	 * @return
	 */
	public Object applyIfUnsupported(Object value) throws DatabaseFacadeException ;
}
